/*
 * @Author: wuqingchun
 * @Date: 2024-10-14 15:18:45
 * @Description: 
 * @LastEditors: wuqingchun
 * @LastEditTime: 2024-10-16 09:36:38
 */
#ifndef __REDIS_CLIENT_H__
#define __REDIS_CLIENT_H__

#include <string>
#include <thread>
#include <atomic>
#include <mutex>

#include <sys/time.h>
#include <hiredis.h>

#include "block_queue.h"

#define MD_DEPTH 5

struct tick
{
    int32_t time;//行情更新时间
    int16_t milli;//行情更新ms
    char instrument_id[16]; //合约代码
    int64_t volume; //成交量
    double last_price; //最新价
    double turnover;//成交额
    int64_t openinterest;//持仓量
    double bid_price[MD_DEPTH];//买一价---买五价
    int32_t bid_vol[MD_DEPTH];//买一量---买五量
    double ask_price[MD_DEPTH];//卖一价---卖五价
    int32_t ask_vol[MD_DEPTH];//卖一量---卖五量
	int instrument_index;//合约索引，下单赋值到order_t的instrument_index字段中
    int32_t tradingday;//交易日，内部预留，缓存预热使用
    uint64_t localtime;//行情本地接收时间
};

class CRedisClient
{
public:
    enum RedisClientState
    {
        REDIS_STATE_UNINT,
        REDIS_STATE_READY,
        REDIS_STATE_CONNECTED,
        REDIS_STATE_DISCONNECT
    };
public:
    CRedisClient();
    ~CRedisClient();
    
    int32_t Start(const char* pcHost, uint16_t usPort);
    void Stop();
    int32_t PushMarketData(const tick& refTick);

    int32_t GetLatestMarketData(tick& refTick);
    int32_t GetMarketData(int32_t iTradingDay, int32_t iBeginTime, int32_t iEndTime, std::vector<tick>& refTickVec);
private:
    int32_t __Connect();
    void __ThreadConnectMgrFunc();

    int32_t __SendHeartBeat();

private:
    std::string m_strHost;
    uint16_t    m_usPort;
    struct timeval m_stTimeOut{1,0};
    
    //  hiredis 连接上下文
    redisContext* m_pstRedisCtx = nullptr;
    std::thread m_objConnMgrThread; // 连接管理线程
    volatile bool m_bConnMgrRunning = false;
    std::mutex m_objMtx;
private://static member
    static std::atomic<RedisClientState> m_atmState;
};

using RedisClientState = CRedisClient::RedisClientState;

#endif //__REDIS_CLIENT_H__